package untiring07;

public class J26_TypeCasting {

	// *모든 클래스의 조상
	// 모든 클래스는 자동적으로 java.lang.Object 를 확장함
	// 즉, Object 클래스는 자바에서 궁극의 super클래스임
	// 기본적으로 Objecr 클래스에는 7개의 메서드가 정의도어 있고,
	// 하위 클래스에서는 이것을 재정의해서 적절히 사용가능
	// *equals- 기존 객체와 매개변수로 전달된 객체와 비교
	// 객체 비교가 제대로 이뤄질려면 메서드를 재정의하고 구현해야 함
	// *hashcode- 객체의 해시코드를 출력함
	// 객체는 일반적으로 heap 에 생성됨 heap에 생성된 객체의 메모리 주소를 바탕으로 만들어지는
	// 유일한 코드값을 의미
	// *toString - 객체에 대한 설명을 출력함

	// 다형성polymorphism
	// OOP의 중요 개념 중 하나
	// 특정 유형의 프로그래밍 요소(변수)가 상황에 따라 다양한 유형의 변수로 바뀔 수 있는 특성을 의미
	// 주로 상속관계에 있는 클래스간에서 나타나는 특별한 성질
	//
	// is-a 관계확인
	// 특정 객체가 어떤 유형과 동일한지 또는 상속관계인지 알아볼때 instanceof예약어를 사용
	
	
	
	
	
	
	
	
	
	
	

	public static void main(String[] args) {
		Object obj = new Object();

		J25_Animal a = new J25_Animal();
		J25_Fish f = new J25_Fish();
		a = new J25_Fish();
		// Fish 는 Animal을 확장했기 때문에 Animal 객체에 Fish객체를 받을 수 있음
		// 하위 객체를 상위 객체로 cast하는 경우 이것을upcasting 이라 함

		// f = (J25_Fish)new J25_Animal();
		// 상위 객체를 하위 객체로 cast하는 경우 이것을downcasting 이라 함
		// 이떄 명시적으로 괄호안에 cast 할 클래스 자료형을 명시

		// 스타크래프트 게임내에서 해병, 불곰, 의무병을 생산하는 경우
		Marine m1 = new Marine();
		Firebat f1 = new Firebat();
		Medic d1 = new Medic();

		// 다형성을 근거로 테란유닛 생산 (upcasting)
		// 즉, Marine 유닛은 상황에 따라 TerranUnits 도 될 수있다는 의미
		TerranUnits t1 = new Marine();
		t1.sayUnit();
		t1.sayUnit((Marine) t1);
		TerranUnits t2 = new Firebat();// upcasting
		t2.sayUnit();
		t2.sayUnit((Firebat) t2); // downcasting
		TerranUnits t3 = new Medic();
		t3.sayUnit();
		t3.sayUnit((Medic) t3);

		AllianceUnit a1 = new Human();
		AllianceUnit a2 = new Wolf();
		AllianceUnit a3 = new Nom();
		
		//객체유형 확인하기
		J26_TypeCasting t = new J26_TypeCasting();
		if( t instanceof java.lang.Object)
			System.out.println("t 는 Object의 자손");
		
		if(m1 instanceof TerranUnits) // is-a
			System.out.println("해병은 테란유닛의 자손");
		
		if(m1 instanceof Marine) //동질성
			System.out.println("m1은 해병임");

	}
	// TerranUnit - Marine , Firebat , Medic

}

class TerranUnits {
	public void sayUnit() {
		System.out.println("저는 테란유닛입니다");
	}

	public void sayUnit(Marine m) {
		System.out.println("저는 해병입니다");
	}

	public void sayUnit(Firebat m) {
		System.out.println("저는 불곰입니다");
	}

	public void sayUnit(Medic m) {
		System.out.println("저는 의무병입니다");
	}
}

class Marine extends TerranUnits {

}

class Firebat extends TerranUnits {

}

class Medic extends TerranUnits {

}

// wow
class AllianceUnit {

}

class Human extends AllianceUnit {

}

class Wolf extends AllianceUnit {

}

class Nom extends AllianceUnit {

}
